#include <common.hpp>
#include "TreeVisualizer2D.hpp"

namespace zzz{
void zzz::TreeVisualizer2D::Rerange(int gap)
{
  if (direction==0)
  {
    int treeheight=1;
    int centerx=tree_.GetHead()->v->posx_+(tree_.GetHead()->v->bbox_.Min(0)+tree_.GetHead()->v->bbox_.Max(0))/2;
    int lastheight=tree_.GetHead()->v->posy_+tree_.GetHead()->v->bbox_.Max(1);
    lastheight+=gap;
    while(true)
    {
      vector<TreeNode<VisualizeNode2D*> * > nodes=tree_.GetHead()->GetSameHeightSons(treeheight);
      if (nodes.empty()) break;
      int curwidth=(nodes.size()-1)*gap;
      int maxheight=0;
      for (size_t i=0; i<nodes.size(); i++)
      {
        curwidth+=nodes[i]->v->bbox_.Diff(0);
        maxheight=Max(maxheight,nodes[i]->v->bbox_.Diff(1));
      }
      curwidth=centerx-curwidth/2;
      lastheight+=maxheight;
      for (size_t i=0; i<nodes.size(); i++)
      {
        nodes[i]->v->posx_=curwidth-nodes[i]->v->bbox_.Min(0);
        nodes[i]->v->posy_=lastheight-nodes[i]->v->bbox_.Max(1);
        curwidth+=nodes[i]->v->bbox_.Diff(0)+gap;
      }
      lastheight+=gap;
      treeheight++;
    }
  }

  if (direction==1)
  {
    int treeheight=1;
    int centery=tree_.GetHead()->v->posy_+(tree_.GetHead()->v->bbox_.Min(1)+tree_.GetHead()->v->bbox_.Max(1))/2;
    int lastwidth=tree_.GetHead()->v->posy_+tree_.GetHead()->v->bbox_.Max(0);
    lastwidth+=gap;
    while(true)
    {
      vector<TreeNode<VisualizeNode2D*> * > nodes=tree_.GetHead()->GetSameHeightSons(treeheight);
      if (nodes.empty()) break;
      int curheight=(nodes.size()-1)*gap;
      int maxwidth=0;
      for (size_t i=0; i<nodes.size(); i++)
      {
        curheight+=nodes[i]->v->bbox_.Diff(1);
        maxwidth=Max(maxwidth,nodes[i]->v->bbox_.Diff(0));
      }
      curheight=centery-curheight/2;
      lastwidth+=maxwidth;
      for (size_t i=0; i<nodes.size(); i++)
      {
        nodes[i]->v->posy_=curheight-nodes[i]->v->bbox_.Min(1);
        nodes[i]->v->posx_=lastwidth-nodes[i]->v->bbox_.Max(0);
        curheight+=nodes[i]->v->bbox_.Diff(1)+gap;
      }
      lastwidth+=gap;
      treeheight++;
    }
  }
}

void zzz::TreeVisualizer2D::Draw()
{
  deque<TreeNode<VisualizeNode2D*> *> q;
  q.push_back(tree_.GetHead());
  while(!q.empty())
  {
    TreeNode<VisualizeNode2D*>* cur=q.front();
    cur->v->DrawPixels(renderer_);
    for (size_t i=0; i<cur->sons.size(); i++)
    {
      //TODO: draw line
      q.push_back(cur->sons[i]);
    }
    q.pop_front();
  }
}
}